class IUP_MULTI_BOX
-- Creates a void container for composing elements in a irregular grid. It is 
-- a box that arranges the elements it contains from top to bottom and from 
-- left to right, by distributing the elements in lines or in columns. But its 
-- EXPAND attribute does not behave as a regular container, instead it behaves 
-- as a regular element expanding into the available space.
--
-- The child elements are added to the control just like a vbox and hbox, 
-- sequentially. Then they are distributed accordingly the ORIENTATION 
-- attribute. When ORIENTATION=HORIZONTAL children are distributed from left to 
-- right on the first line until the line does not fits more elements according 
-- to the multibox current width, then on the second line, and so on. When 
-- ORIENTATION=VERTICAL children are distributed from top to bottom on the 
-- first column until columns does not fits more elements according to the 
-- multibox current height, then on the second column, and so on.
--
-- Because of that its elements can overlap other elements in the dialog, so 
-- the ideal combination is to put the IUP_MULTI_BOX inside an IUP_SCROLL_BOX.
--
-- IMPORTANT: the actual element distribution in the container is done only 
-- after the natural size of the dialog is computed because it needs the 
-- current with or height to determine which elements will fit in the current 
-- space according to the orientation. The first time the multibox natural size 
-- is computed it returns simply the largest width and the highest height among 
-- the children. The next time it will use the size previously calculated with 
-- the line/column breaks, to avoid obtaining an outdated layout call "refresh" 
-- or "map" before showing the dialog (when the layout will be updated again).
--
-- It does not have a native representation.
--
-- Notes:
--
-- The box can be created with no elements and be dynamic filled using "append" 
-- or "insert".
--
-- The box will NOT expand its children in any condition.
--
-- The number of elements in a line when ORIENTATION=HORIZONTAL can be very 
-- different depending on the children sizes and line/column breaks. The same 
-- for elements in a column when ORIENTATION=VERTICAL.
inherit
	IUP_CONTAINER
	IUP_WIDGET_EXPAND
	IUP_WIDGET_WID
	IUP_WIDGET_SIZE
	IUP_WIDGET_RASTERSIZE
	IUP_WIDGET_FONT
	IUP_WIDGET_CLIENTSIZE
	IUP_WIDGET_CLIENTOFFSET
	IUP_WIDGET_POSITION
	IUP_WIDGET_MAXMIN_SIZE
	IUP_WIDGET_NAME
	IUP_WIDGET_CUSTOM_ATTRIBUTES

create {ANY}
   multi_box_empty,
   multi_box

feature {ANY}

	multi_box_empty
	   -- Create an empty multi box.
		local
			p, a_multi_box: POINTER
		do
			a_multi_box := int_multi_box_empty (p)
			set_widget(a_multi_box)
		end
		
	multi_box (col: ARRAY[IUP_WIDGET])
	   -- Create a new multi box containing the list of widgets.
		local
         iterator: ITERATOR[IUP_WIDGET]; i: INTEGER; arg: NATIVE_ARRAY[POINTER]; s: IUP_WIDGET; a_multi_box: POINTER
		do
			i := col.count
			arg := arg.calloc(i)
			iterator := col.new_iterator
			i := 0
			
			from
				iterator.start
         until
				iterator.is_off
         loop
            s := iterator.item
            arg.put(s.widget, i)
				iterator.next
            i := i + 1
         end

			a_multi_box := int_multi_box (arg.to_external)
			set_widget(a_multi_box)
		end

	-- Commands to handle attributes.

	set_child_max_size (width: INTEGER; height: INTEGER)
		-- (non inheritable): when defined limits the size of all children to a 
		-- given maximum size. This affects each child size.
		require
			non_negative: width >= 0
							  height >= 0
		local
			size: STRING
		do
			size := width.to_string
			size.append_string("x")
			size.append_string(height.to_string)

			iup_open.set_attribute(Current, "CHILDMAXSIZE", size)
		end

	set_child_min_size (width: INTEGER; height: INTEGER)
		-- (non inheritable): when defined limits the space occupied by a child 
		-- to a given minimum size. Uses the format "widthxheight". This does not 
		-- affects the children size.
		require
			non_negative: width >= 0
							  height >= 0
		local
			size: STRING
		do
			size := width.to_string
			size.append_string("x")
			size.append_string(height.to_string)

			iup_open.set_attribute(Current, "CHILDMINSPACE", size)
		end

	set_vertical_gap (gap: INTEGER)
	-- Defines a vertical space in pixels between elements. Default: 0.
		require
			non_negative: gap >= 0
		do
			iup_open.set_attribute(Current, "GAPVERT", gap.to_string)
		end

	set_vertical_char_gap (gap: INTEGER)
		-- Defines a vertical space between elements in the same units of the 
		-- SIZE attribute for the height. Default: 0.
		require
			non_negative: gap >= 0
		do
			iup_open.set_attribute(Current, "CGAPVERT", gap.to_string)
		end

	set_horizontal_gap (gap: INTEGER)
	-- Defines a horizontal space in pixels between elements. Default: 0.
		require
			non_negative: gap >= 0
		do
			iup_open.set_attribute(Current, "GAPHORIZ", gap.to_string)
		end

	set_horizontal_char_gap (gap: INTEGER)
		-- Defines a horizontal space between elements in the same units of the 
		-- SIZE attribute for the width. Default: 0.
		require
			non_negative: gap >= 0
		do
			iup_open.set_attribute(Current, "CGAPHORIZ", gap.to_string)
		end

	set_vertical_ngap (gap: INTEGER)
	-- Like "set_vertical_gap" but non inheritable.
		require
			non_negative: gap >= 0
		do
			iup_open.set_attribute(Current, "NGAPVERT", gap.to_string)
		end

	set_vertical_char_ngap (gap: INTEGER)
		-- Like "set_vertical_char_gap" but non inheritable.
		require
			non_negative: gap >= 0
		do
			iup_open.set_attribute(Current, "NCGAPVERT", gap.to_string)
		end

	set_horizontal_ngap (gap: INTEGER)
	-- Like "set_horizontal_gap" but non inheritable.
		require
			non_negative: gap >= 0
		do
			iup_open.set_attribute(Current, "NGAPHORIZ", gap.to_string)
		end

	set_horizontal_char_ngap (gap: INTEGER)
		-- Like "set_horizontal_char_gap" but non inheritable.
		require
			non_negative: gap >= 0
		do
			iup_open.set_attribute(Current, "NCGAPHORIZ", gap.to_string)
		end

	set_margin (width: INTEGER; height: INTEGER)
		-- Defines a margin in pixels, width and height are integer values 
		-- corresponding to the horizontal and vertical margins, respectively. 
		-- Default: "0x0" (no margin).
		require
			non_negative: width >= 0
							  height >= 0
		local
			size: STRING
		do
			size := width.to_string
			size.append_string("x")
			size.append_string(height.to_string)

			iup_open.set_attribute(Current, "MARGIN", size)
		end

	set_char_margin (width: INTEGER; height: INTEGER)
		-- Like "set_margin" but in the same units of the SIZE attribute.
		require
			non_negative: width >= 0
							  height >= 0
		local
			size: STRING
		do
			size := width.to_string
			size.append_string("x")
			size.append_string(height.to_string)

			iup_open.set_attribute(Current, "CMARGIN", size)
		end

	set_nmargin (width: INTEGER; height: INTEGER)
		-- Like "set_margin" but non inheritable.
		require
			non_negative: width >= 0
							  height >= 0
		local
			size: STRING
		do
			size := width.to_string
			size.append_string("x")
			size.append_string(height.to_string)

			iup_open.set_attribute(Current, "NMARGIN", size)
		end

	set_nchar_margin (width: INTEGER; height: INTEGER)
		-- Like "set_char_margin" but non inheritable.
		require
			non_negative: width >= 0
							  height >= 0
		local
			size: STRING
		do
			size := width.to_string
			size.append_string("x")
			size.append_string(height.to_string)

			iup_open.set_attribute(Current, "NCMARGIN", size)
		end

	number_of_columns: INTEGER
			-- Returns the number of columns when orientation is vertical. Returns 
			-- 0 otherwise.
		local
			str: STRING
		do
			str := iup_open.get_attribute(Current, "NUMCOL")

			Result := str.to_integer
		end

	number_of_lines: INTEGER
			-- Returns the number of lines when orientation is horizontal. Returns 
			-- 0 otherwise.
		local
			str: STRING
		do
			str := iup_open.get_attribute(Current, "NUMLIN")

			Result := str.to_integer
		end

	set_vertical_orientation
		do
			iup_open.set_attribute(Current, "ORIENTATION", "VERTICAL")
		end

	set_horizontal_orientation
		-- The default value.
		do
			iup_open.set_attribute(Current, "ORIENTATION", "HORIZONTAL")
		end

feature {}

	-- Internals
	
	int_multi_box_empty (arguments: POINTER): POINTER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupMultiBox"
         }"
      end
	
   int_multi_box (arguments: POINTER): POINTER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupMultiBoxv"
         }"
      end

end -- class IUP_MULTI_BOX

-- The MIT License (MIT)

-- Copyright (c) 2019 by German A. Arias

-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in 
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-- SOFTWARE.




